﻿using Sustainalytics.Claims;
using Sustainalytics.Entities;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Web.Http;

namespace Sustainalytics.Portfolios.Service.Utility
{
    using Newtonsoft.Json;
    using System;
    using System.Net.Http;

    public static class PortfolioClaimsCheckerExtensions
    {
        public static bool ValidatePortfolioManagementClaim(this IClaimsChecker claimsChecker, ApiController controller)
        {
            return ApiControllerValidator(claimsChecker, controller, new List<ResourceParameters>() { new ResourceParameters { Key = "shortName", Value = "portfoliomanagement" } });
        }

        public static bool ValidateSubscribeToPortfolioClaim(this IClaimsChecker claimsChecker, ApiController controller, HttpContent content)
        {
            var methodContent = content.ReadAsStringAsync().Result;
            if (string.IsNullOrEmpty(methodContent))
            {
                return ApiControllerValidator(claimsChecker, controller, null);
            }

            var subscription = JsonConvert.DeserializeObject<SubscribeToPortfolio>(methodContent);

            if (subscription != null)
            {
                string sn = string.Empty;

                switch (subscription.Frequency)
                {
                    case 1:
                        sn = "semimonthly";
                        break;

                    case 2:
                        sn = "monthly";
                        break;

                    case 3:
                        sn = "quarterly";
                        break;
                }

                return ApiControllerValidator(claimsChecker, controller, new List<ResourceParameters>() { new ResourceParameters { Key = "alert", Value = sn } });
            }

            return false;
        }

        public static bool Validate(this IClaimsChecker claimsChecker, ApiController ctrl, List<ResourceParameters> parameters)
        {
            // get current principal
            var principal = (ClaimsPrincipal)ctrl.User;

            // get route prefix
            object[] attrs = ctrl.GetType().GetCustomAttributes(typeof(RoutePrefixAttribute), false);
            RoutePrefixAttribute routePrefixAttrs = attrs == null || attrs.Length == 0 ? null : attrs.Select(a => (RoutePrefixAttribute)a).FirstOrDefault();

            // get HTTP Method
            string httpMethod = ctrl.Request.Method.Method;

            bool valid = claimsChecker.Validate(
                claimsPrincipal: principal,
                resource: routePrefixAttrs == null ? null : routePrefixAttrs.Prefix,
                verb: httpMethod,
                parameters: parameters);

            return valid;
        }

        public static Func<IClaimsChecker, ApiController, List<ResourceParameters>, bool> ApiControllerValidator =
            (checker, controller, arg3) => checker.Validate(controller, arg3);
    }
}
